package sdp.server.vision;

import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
import sdp.server.BallState;
import sdp.server.ScreenProjection;

public class BallModel extends EntityModel {
	private ScreenProjection screen;
	private double           area            = 105.0;
	private double           areaTolerance   = 0.5;
	private double           circTolerance   = 0.6;
	
	public BallModel( CvMemStorage storage, IplImage channel, IplImage temp1, ScreenProjection screen ) {
		super( storage, channel, temp1 );
		this.screen = screen;
		setRoiSize( 128 );
	}
	
	@Override
	protected double contourScore( CvSeq c, CvMoments moments ) {
		CvRect  bound  = cvBoundingRect( c, 1 );
		double  radius = (double)(bound.width() + bound.height()) / 4;
		double  area   = computeArea( moments );
		
		double  circProp = Math.abs( radius / Math.sqrt( area / Math.PI ) - 1.0 );
		double  areaProp = Math.abs( area / this.area - 1.0 );
				
		boolean circTest = circProp < circTolerance;
		boolean areaTest = areaProp < areaTolerance;
		if( circTest && areaTest )
			return - circProp - areaProp;
		else
			return Double.NaN;
	}
	
	public void update( BallState state, double timeStep ) {
		if( getContour() != null ) {
			state.update( screen.unprojectPosition( getCentroid() ), timeStep );
		} else {
			state.update( null, timeStep );
		}
	}
}
